;
; Sudoku puzzle rules, encoded in such a way that the pattern matcher
; can try to do a brute-force exploration.
;
(use-modules (opencog))


; Definition of a number.  Cells in the sudoku puzzle can only contain
; numbers.
(Edge (Predicate "IsNumber") (Concept "one"))
(Edge (Predicate "IsNumber") (Concept "two"))
(Edge (Predicate "IsNumber") (Concept "three"))
(Edge (Predicate "IsNumber") (Concept "four"))
(Edge (Predicate "IsNumber") (Concept "five"))
(Edge (Predicate "IsNumber") (Concept "six"))
(Edge (Predicate "IsNumber") (Concept "seven"))
(Edge (Predicate "IsNumber") (Concept "eight"))
(Edge (Predicate "IsNumber") (Concept "nine"))

; The set of numbers that can be chosen from. Every row, column
; and three-by-three box must hold this set.
(ExclusiveLink
	(Concept "one")
	(Concept "two")
	(Concept "three")
	(Concept "four")
	(Concept "five")
	(Concept "six")
	(Concept "seven")
	(Concept "eight")
	(Concept "nine")
)

; The contents of the cells must be numbers!
; Actually, this constraint will not be needed, as the requirement that
; the columns, rows and boxes be a number set is sufficient.  So the
; below only adds complexity to the problem, slowing down solving.
(define (cells-are-numbers-9x9)
	(list
		(Edge (Predicate "IsNumber") (Variable "$cell_11"))
		(Edge (Predicate "IsNumber") (Variable "$cell_12"))
		(Edge (Predicate "IsNumber") (Variable "$cell_13"))
		(Edge (Predicate "IsNumber") (Variable "$cell_14"))
		(Edge (Predicate "IsNumber") (Variable "$cell_15"))
		(Edge (Predicate "IsNumber") (Variable "$cell_16"))
		(Edge (Predicate "IsNumber") (Variable "$cell_17"))
		(Edge (Predicate "IsNumber") (Variable "$cell_18"))
		(Edge (Predicate "IsNumber") (Variable "$cell_19"))

		(Edge (Predicate "IsNumber") (Variable "$cell_21"))
		(Edge (Predicate "IsNumber") (Variable "$cell_22"))
		(Edge (Predicate "IsNumber") (Variable "$cell_23"))
		(Edge (Predicate "IsNumber") (Variable "$cell_24"))
		(Edge (Predicate "IsNumber") (Variable "$cell_25"))
		(Edge (Predicate "IsNumber") (Variable "$cell_26"))
		(Edge (Predicate "IsNumber") (Variable "$cell_27"))
		(Edge (Predicate "IsNumber") (Variable "$cell_28"))
		(Edge (Predicate "IsNumber") (Variable "$cell_29"))

		(Edge (Predicate "IsNumber") (Variable "$cell_31"))
		(Edge (Predicate "IsNumber") (Variable "$cell_32"))
		(Edge (Predicate "IsNumber") (Variable "$cell_33"))
		(Edge (Predicate "IsNumber") (Variable "$cell_34"))
		(Edge (Predicate "IsNumber") (Variable "$cell_35"))
		(Edge (Predicate "IsNumber") (Variable "$cell_36"))
		(Edge (Predicate "IsNumber") (Variable "$cell_37"))
		(Edge (Predicate "IsNumber") (Variable "$cell_38"))
		(Edge (Predicate "IsNumber") (Variable "$cell_39"))

		(Edge (Predicate "IsNumber") (Variable "$cell_41"))
		(Edge (Predicate "IsNumber") (Variable "$cell_42"))
		(Edge (Predicate "IsNumber") (Variable "$cell_43"))
		(Edge (Predicate "IsNumber") (Variable "$cell_44"))
		(Edge (Predicate "IsNumber") (Variable "$cell_45"))
		(Edge (Predicate "IsNumber") (Variable "$cell_46"))
		(Edge (Predicate "IsNumber") (Variable "$cell_47"))
		(Edge (Predicate "IsNumber") (Variable "$cell_48"))
		(Edge (Predicate "IsNumber") (Variable "$cell_49"))

		(Edge (Predicate "IsNumber") (Variable "$cell_51"))
		(Edge (Predicate "IsNumber") (Variable "$cell_52"))
		(Edge (Predicate "IsNumber") (Variable "$cell_53"))
		(Edge (Predicate "IsNumber") (Variable "$cell_54"))
		(Edge (Predicate "IsNumber") (Variable "$cell_55"))
		(Edge (Predicate "IsNumber") (Variable "$cell_56"))
		(Edge (Predicate "IsNumber") (Variable "$cell_57"))
		(Edge (Predicate "IsNumber") (Variable "$cell_58"))
		(Edge (Predicate "IsNumber") (Variable "$cell_59"))

		(Edge (Predicate "IsNumber") (Variable "$cell_61"))
		(Edge (Predicate "IsNumber") (Variable "$cell_62"))
		(Edge (Predicate "IsNumber") (Variable "$cell_63"))
		(Edge (Predicate "IsNumber") (Variable "$cell_64"))
		(Edge (Predicate "IsNumber") (Variable "$cell_65"))
		(Edge (Predicate "IsNumber") (Variable "$cell_66"))
		(Edge (Predicate "IsNumber") (Variable "$cell_67"))
		(Edge (Predicate "IsNumber") (Variable "$cell_68"))
		(Edge (Predicate "IsNumber") (Variable "$cell_69"))

		(Edge (Predicate "IsNumber") (Variable "$cell_71"))
		(Edge (Predicate "IsNumber") (Variable "$cell_72"))
		(Edge (Predicate "IsNumber") (Variable "$cell_73"))
		(Edge (Predicate "IsNumber") (Variable "$cell_74"))
		(Edge (Predicate "IsNumber") (Variable "$cell_75"))
		(Edge (Predicate "IsNumber") (Variable "$cell_76"))
		(Edge (Predicate "IsNumber") (Variable "$cell_77"))
		(Edge (Predicate "IsNumber") (Variable "$cell_78"))
		(Edge (Predicate "IsNumber") (Variable "$cell_79"))

		(Edge (Predicate "IsNumber") (Variable "$cell_81"))
		(Edge (Predicate "IsNumber") (Variable "$cell_82"))
		(Edge (Predicate "IsNumber") (Variable "$cell_83"))
		(Edge (Predicate "IsNumber") (Variable "$cell_84"))
		(Edge (Predicate "IsNumber") (Variable "$cell_85"))
		(Edge (Predicate "IsNumber") (Variable "$cell_86"))
		(Edge (Predicate "IsNumber") (Variable "$cell_87"))
		(Edge (Predicate "IsNumber") (Variable "$cell_88"))
		(Edge (Predicate "IsNumber") (Variable "$cell_89"))

		(Edge (Predicate "IsNumber") (Variable "$cell_91"))
		(Edge (Predicate "IsNumber") (Variable "$cell_92"))
		(Edge (Predicate "IsNumber") (Variable "$cell_93"))
		(Edge (Predicate "IsNumber") (Variable "$cell_94"))
		(Edge (Predicate "IsNumber") (Variable "$cell_95"))
		(Edge (Predicate "IsNumber") (Variable "$cell_96"))
		(Edge (Predicate "IsNumber") (Variable "$cell_97"))
		(Edge (Predicate "IsNumber") (Variable "$cell_98"))
		(Edge (Predicate "IsNumber") (Variable "$cell_99"))
	)
)

; Twenty-seven solution constraints.  There are nine row, nine column,
; and nine box constraints: each row, column and box must form the 
; set of numerals.
;
; I've avoided using whizzy scheme for-loops to specify these, and
; instead tediously wrote them out by hand.  The goal here is to make
; the structure slightly easier to read and understand.
;
; First, nine row constraints
(define (row1)
	(ExclusiveLink
		(Variable "$cell_11")
		(Variable "$cell_12")
		(Variable "$cell_13")
		(Variable "$cell_14")
		(Variable "$cell_15")
		(Variable "$cell_16")
		(Variable "$cell_17")
		(Variable "$cell_18")
		(Variable "$cell_19")
	)
)
(define (row2)
	(ExclusiveLink
		(Variable "$cell_21")
		(Variable "$cell_22")
		(Variable "$cell_23")
		(Variable "$cell_24")
		(Variable "$cell_25")
		(Variable "$cell_26")
		(Variable "$cell_27")
		(Variable "$cell_28")
		(Variable "$cell_29")
	)
)
(define (row3)
	(ExclusiveLink
		(Variable "$cell_31")
		(Variable "$cell_32")
		(Variable "$cell_33")
		(Variable "$cell_34")
		(Variable "$cell_35")
		(Variable "$cell_36")
		(Variable "$cell_37")
		(Variable "$cell_38")
		(Variable "$cell_39")
	)
)
(define (row4)
	(ExclusiveLink
		(Variable "$cell_41")
		(Variable "$cell_42")
		(Variable "$cell_43")
		(Variable "$cell_44")
		(Variable "$cell_45")
		(Variable "$cell_46")
		(Variable "$cell_47")
		(Variable "$cell_48")
		(Variable "$cell_49")
	)
)
(define (row5)
	(ExclusiveLink
		(Variable "$cell_51")
		(Variable "$cell_52")
		(Variable "$cell_53")
		(Variable "$cell_54")
		(Variable "$cell_55")
		(Variable "$cell_56")
		(Variable "$cell_57")
		(Variable "$cell_58")
		(Variable "$cell_59")
	)
)
(define (row6)
	(ExclusiveLink
		(Variable "$cell_61")
		(Variable "$cell_62")
		(Variable "$cell_63")
		(Variable "$cell_64")
		(Variable "$cell_65")
		(Variable "$cell_66")
		(Variable "$cell_67")
		(Variable "$cell_68")
		(Variable "$cell_69")
	)
)
(define (row7)
	(ExclusiveLink
		(Variable "$cell_71")
		(Variable "$cell_72")
		(Variable "$cell_73")
		(Variable "$cell_74")
		(Variable "$cell_75")
		(Variable "$cell_76")
		(Variable "$cell_77")
		(Variable "$cell_78")
		(Variable "$cell_79")
	)
)
(define (row8)
	(ExclusiveLink
		(Variable "$cell_81")
		(Variable "$cell_82")
		(Variable "$cell_83")
		(Variable "$cell_84")
		(Variable "$cell_85")
		(Variable "$cell_86")
		(Variable "$cell_87")
		(Variable "$cell_88")
		(Variable "$cell_89")
	)
)
(define (row9)
	(ExclusiveLink
		(Variable "$cell_91")
		(Variable "$cell_92")
		(Variable "$cell_93")
		(Variable "$cell_94")
		(Variable "$cell_95")
		(Variable "$cell_96")
		(Variable "$cell_97")
		(Variable "$cell_98")
		(Variable "$cell_99")
	)
)

;; Next, nine column constraints
(define (col1)
	(ExclusiveLink
		(Variable "$cell_11")
		(Variable "$cell_21")
		(Variable "$cell_31")
		(Variable "$cell_41")
		(Variable "$cell_51")
		(Variable "$cell_61")
		(Variable "$cell_71")
		(Variable "$cell_81")
		(Variable "$cell_91")
	)
)
(define (col2)
	(ExclusiveLink
		(Variable "$cell_12")
		(Variable "$cell_22")
		(Variable "$cell_32")
		(Variable "$cell_42")
		(Variable "$cell_52")
		(Variable "$cell_62")
		(Variable "$cell_72")
		(Variable "$cell_82")
		(Variable "$cell_92")
	)
)
(define (col3)
	(ExclusiveLink
		(Variable "$cell_13")
		(Variable "$cell_23")
		(Variable "$cell_33")
		(Variable "$cell_43")
		(Variable "$cell_53")
		(Variable "$cell_63")
		(Variable "$cell_73")
		(Variable "$cell_83")
		(Variable "$cell_93")
	)
)
(define (col4)
	(ExclusiveLink
		(Variable "$cell_14")
		(Variable "$cell_24")
		(Variable "$cell_34")
		(Variable "$cell_44")
		(Variable "$cell_54")
		(Variable "$cell_64")
		(Variable "$cell_74")
		(Variable "$cell_84")
		(Variable "$cell_94")
	)
)
(define (col5)
	(ExclusiveLink
		(Variable "$cell_15")
		(Variable "$cell_25")
		(Variable "$cell_35")
		(Variable "$cell_45")
		(Variable "$cell_55")
		(Variable "$cell_65")
		(Variable "$cell_75")
		(Variable "$cell_85")
		(Variable "$cell_95")
	)
)
(define (col6)
	(ExclusiveLink
		(Variable "$cell_16")
		(Variable "$cell_26")
		(Variable "$cell_36")
		(Variable "$cell_46")
		(Variable "$cell_56")
		(Variable "$cell_66")
		(Variable "$cell_76")
		(Variable "$cell_86")
		(Variable "$cell_96")
	)
)
(define (col7)
	(ExclusiveLink
		(Variable "$cell_17")
		(Variable "$cell_27")
		(Variable "$cell_37")
		(Variable "$cell_47")
		(Variable "$cell_57")
		(Variable "$cell_67")
		(Variable "$cell_77")
		(Variable "$cell_87")
		(Variable "$cell_97")
	)
)
(define (col8)
	(ExclusiveLink
		(Variable "$cell_18")
		(Variable "$cell_28")
		(Variable "$cell_38")
		(Variable "$cell_48")
		(Variable "$cell_58")
		(Variable "$cell_68")
		(Variable "$cell_78")
		(Variable "$cell_88")
		(Variable "$cell_98")
	)
)
(define (col9)
	(ExclusiveLink
		(Variable "$cell_19")
		(Variable "$cell_29")
		(Variable "$cell_39")
		(Variable "$cell_49")
		(Variable "$cell_59")
		(Variable "$cell_69")
		(Variable "$cell_79")
		(Variable "$cell_89")
		(Variable "$cell_99")
	)
)

;; And finally, 9 box constraints
(define (box11)
	(ExclusiveLink
		(Variable "$cell_11")
		(Variable "$cell_12")
		(Variable "$cell_13")
		(Variable "$cell_21")
		(Variable "$cell_22")
		(Variable "$cell_23")
		(Variable "$cell_31")
		(Variable "$cell_32")
		(Variable "$cell_33")
	)
)

(define (box14)
	(ExclusiveLink
		(Variable "$cell_14")
		(Variable "$cell_15")
		(Variable "$cell_16")
		(Variable "$cell_24")
		(Variable "$cell_25")
		(Variable "$cell_26")
		(Variable "$cell_34")
		(Variable "$cell_35")
		(Variable "$cell_36")
	)
)

(define (box17)
	(ExclusiveLink
		(Variable "$cell_17")
		(Variable "$cell_18")
		(Variable "$cell_19")
		(Variable "$cell_27")
		(Variable "$cell_28")
		(Variable "$cell_29")
		(Variable "$cell_37")
		(Variable "$cell_38")
		(Variable "$cell_39")
	)
)

(define (box41)
	(ExclusiveLink
		(Variable "$cell_41")
		(Variable "$cell_42")
		(Variable "$cell_43")
		(Variable "$cell_51")
		(Variable "$cell_52")
		(Variable "$cell_53")
		(Variable "$cell_61")
		(Variable "$cell_62")
		(Variable "$cell_63")
	)
)

(define (box44)
	(ExclusiveLink
		(Variable "$cell_44")
		(Variable "$cell_45")
		(Variable "$cell_46")
		(Variable "$cell_54")
		(Variable "$cell_55")
		(Variable "$cell_56")
		(Variable "$cell_64")
		(Variable "$cell_65")
		(Variable "$cell_66")
	)
)

(define (box47)
	(ExclusiveLink
		(Variable "$cell_47")
		(Variable "$cell_48")
		(Variable "$cell_49")
		(Variable "$cell_57")
		(Variable "$cell_58")
		(Variable "$cell_59")
		(Variable "$cell_67")
		(Variable "$cell_68")
		(Variable "$cell_69")
	)
)

(define (box71)
	(ExclusiveLink
		(Variable "$cell_71")
		(Variable "$cell_72")
		(Variable "$cell_73")
		(Variable "$cell_81")
		(Variable "$cell_82")
		(Variable "$cell_83")
		(Variable "$cell_91")
		(Variable "$cell_92")
		(Variable "$cell_93")
	)
)

(define (box74)
	(ExclusiveLink
		(Variable "$cell_74")
		(Variable "$cell_75")
		(Variable "$cell_76")
		(Variable "$cell_84")
		(Variable "$cell_85")
		(Variable "$cell_86")
		(Variable "$cell_94")
		(Variable "$cell_95")
		(Variable "$cell_96")
	)
)

(define (box77)
	(ExclusiveLink
		(Variable "$cell_77")
		(Variable "$cell_78")
		(Variable "$cell_79")
		(Variable "$cell_87")
		(Variable "$cell_88")
		(Variable "$cell_89")
		(Variable "$cell_97")
		(Variable "$cell_98")
		(Variable "$cell_99")
	)
)

;; The grand-total set of constraints.
(define (sudoku-constraints)
	(list
		; (cells-are-numbers-9x9) ; constraint isn't needed.
		(row1)
		(row2)
		(row3)
		(row4)
		(row5)
		(row6)
		(row7)
		(row8)
		(row9)
		(col1)
		(col2)
		(col3)
		(col4)
		(col5)
		(col6)
		(col7)
		(col8)
		(col9)
		(box11)
		(box14)
		(box17)
		(box41)
		(box44)
		(box47)
		(box71)
		(box74)
		(box77)
	)
)

; Define the variables to be solved for.
; This is just a big list of all the cells.
;
(define (variable-decls)
	(list
		(Variable "$cell_11")
		(Variable "$cell_12")
		(Variable "$cell_13")
		(Variable "$cell_14")
		(Variable "$cell_15")
		(Variable "$cell_16")
		(Variable "$cell_17")
		(Variable "$cell_18")
		(Variable "$cell_19")

		(Variable "$cell_21")
		(Variable "$cell_22")
		(Variable "$cell_23")
		(Variable "$cell_24")
		(Variable "$cell_25")
		(Variable "$cell_26")
		(Variable "$cell_27")
		(Variable "$cell_28")
		(Variable "$cell_29")

		(Variable "$cell_31")
		(Variable "$cell_32")
		(Variable "$cell_33")
		(Variable "$cell_34")
		(Variable "$cell_35")
		(Variable "$cell_36")
		(Variable "$cell_37")
		(Variable "$cell_38")
		(Variable "$cell_39")

		(Variable "$cell_41")
		(Variable "$cell_42")
		(Variable "$cell_43")
		(Variable "$cell_44")
		(Variable "$cell_45")
		(Variable "$cell_46")
		(Variable "$cell_47")
		(Variable "$cell_48")
		(Variable "$cell_49")

		(Variable "$cell_51")
		(Variable "$cell_52")
		(Variable "$cell_53")
		(Variable "$cell_54")
		(Variable "$cell_55")
		(Variable "$cell_56")
		(Variable "$cell_57")
		(Variable "$cell_58")
		(Variable "$cell_59")

		(Variable "$cell_61")
		(Variable "$cell_62")
		(Variable "$cell_63")
		(Variable "$cell_64")
		(Variable "$cell_65")
		(Variable "$cell_66")
		(Variable "$cell_67")
		(Variable "$cell_68")
		(Variable "$cell_69")

		(Variable "$cell_71")
		(Variable "$cell_72")
		(Variable "$cell_73")
		(Variable "$cell_74")
		(Variable "$cell_75")
		(Variable "$cell_76")
		(Variable "$cell_77")
		(Variable "$cell_78")
		(Variable "$cell_79")

		(Variable "$cell_81")
		(Variable "$cell_82")
		(Variable "$cell_83")
		(Variable "$cell_84")
		(Variable "$cell_85")
		(Variable "$cell_86")
		(Variable "$cell_87")
		(Variable "$cell_88")
		(Variable "$cell_89")

		(Variable "$cell_91")
		(Variable "$cell_92")
		(Variable "$cell_93")
		(Variable "$cell_94")
		(Variable "$cell_95")
		(Variable "$cell_96")
		(Variable "$cell_97")
		(Variable "$cell_98")
		(Variable "$cell_99")
	)
)
